﻿using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

using Microsoft.Practices.Unity;
using PrismContrib.Errors;
using Microsoft.Practices.Composite.Logging;
using Microsoft.Practices.Composite.Events;

using ModuleLibrary.Events;
using ModuleLibrary.Types;
using ModuleLibrary.Extensions;
using ModuleLibrary.LayerDAL;

using InformationModel.Events;
using InformationModel.Types;

using org.ids_adi.iring.referenceData;
using org.ids_adi.qmxf;
using System.Linq;

using OntologyService.Interface.PresentationModels;
using org.iringtools.utility;
using ModuleLibrary.UserControls;
using System.Windows.Media.Imaging;
using System.Windows.Media;
using org.iringtools.library;

namespace InformationModel.UserControls
{
    public class ClassTreeItem : CustomTreeItem
    {
        CustomTreeItem superclasses = null;
        CustomTreeItem subclasses = null;
        CustomTreeItem templates = null;
        CustomTreeItem classifications = null;

        public ClassDefinition ClassDefinition { get; set; }

        /// <summary>
        /// Handles the Selected event of the node control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        public override void nodeSelectedHandler(object sender, RoutedEventArgs e)
        {
            if (!isProcessed)
            {
                Logger.Log(string.Format("node_selected in {0} executing GetQMXF for {1}", GetType().FullName, id),
                    Category.Debug, Priority.None);

                ReferenceDataService.GetClass(id, this);
            }   
           

          UpdateModel();
          FillClassDetailView();         
        
        }

        private void FillClassDetailView()
        {
          PresentationModel.SelectedTreeItem = this;
          PresentationModel.DetailProperties.Clear();

          if (Tag == null)
            return;

          if (Tag is Entity)
          {
            Entity entity = (Entity)Tag;
            KeyValuePair<string, string> keyValuePair = new KeyValuePair<string, string>("Label", entity.label);
            PresentationModel.DetailProperties.Add(keyValuePair);
            keyValuePair = new KeyValuePair<string, string>("Uri", entity.uri);
            PresentationModel.DetailProperties.Add(keyValuePair);
            keyValuePair = new KeyValuePair<string, string>("Repository", entity.repository);
            PresentationModel.DetailProperties.Add(keyValuePair);
          }
          else if (Tag is ClassDefinition)
          {
            ClassDefinition classDefinition = (ClassDefinition)Tag;

            KeyValuePair<string, string> keyValuePair = new KeyValuePair<string, string>("QMXF Type", "Class Definition");
            PresentationModel.DetailProperties.Add(keyValuePair);

            keyValuePair = new KeyValuePair<string, string>("Name", (classDefinition.name.FirstOrDefault() != null ? classDefinition.name.FirstOrDefault().value : string.Empty));
            PresentationModel.DetailProperties.Add(keyValuePair);
            
            GetClassLabel("Identifier", classDefinition.identifier);
            
            keyValuePair = new KeyValuePair<string, string>("Entity Type", (classDefinition.entityType != null ? classDefinition.entityType.reference : string.Empty));
            PresentationModel.DetailProperties.Add(keyValuePair);

            keyValuePair = new KeyValuePair<string, string>("Description", (classDefinition.description.FirstOrDefault() != null ? classDefinition.description.FirstOrDefault().value : string.Empty));
            PresentationModel.DetailProperties.Add(keyValuePair);

            string statusClass = classDefinition.status.FirstOrDefault() != null ? classDefinition.status.FirstOrDefault().Class : string.Empty;
            GetClassLabel("Status Class", statusClass);

            string statusAuthority = classDefinition.status.FirstOrDefault() != null ? classDefinition.status.FirstOrDefault().authority : string.Empty;
            GetClassLabel("Status Authority", statusAuthority);

            string statusFrom = classDefinition.status.FirstOrDefault() != null ? classDefinition.status.FirstOrDefault().from : string.Empty;
            GetClassLabel("Status From", statusFrom);

            string statusTo = classDefinition.status.FirstOrDefault() != null ? classDefinition.status.FirstOrDefault().to : string.Empty;
            GetClassLabel("Status To", statusTo);
          }
        }

        /// <summary>
        /// Handles the selected event of the superclasses control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        public void superclasses_selected(object sender, System.Windows.RoutedEventArgs e)
        {
          if (superclasses.isProcessed)
              return;

          Logger.Log(string.Format("superclasses_selected in {0}", GetType().FullName),
              Category.Debug, Priority.None);

          List<Specialization> specializations = ClassDefinition.specialization;

          foreach (Specialization specialization in specializations)
          {
            string label = specialization.label;

            Entity entity = new Entity
            {
              label = label ?? "[null]",
              repository = "UnKnown",
              uri = specialization.reference,
            };
            superclasses.Items.Add(AddTreeItem(label, entity));
          }

          superclasses.itemTextBlock.Text = "Super Classes (" + specializations.Count + ")";
          superclasses.IsExpanded = false;
          superclasses.isProcessed = true;
          
        }

         /// <summary>
        /// Handles the selected event of the classifications control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        public void classifications_selected(object sender, System.Windows.RoutedEventArgs e)
        {
            if (classifications.isProcessed)
                return;

            Logger.Log(string.Format("classifications_selected in {0}", GetType().FullName),
                Category.Debug, Priority.None);

            List<Classification> classification = ClassDefinition.classification;

            foreach (Classification classificationDetails in classification)
            {
                string label = classificationDetails.label;

                Entity entity = new Entity
                {
                    label = label ?? "[null]",
                    repository = "UnKnown",
                    uri = classificationDetails.reference,
                };
                classifications.Items.Add(AddTreeItem(label, entity));
            }

            classifications.itemTextBlock.Text = "Classifications (" + classification.Count + ")";
            classifications.IsExpanded = false;
            classifications.isProcessed = true;
        }

        /// <summary>
        /// Handles the selected event of the subclasses control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        public void subclasses_selected(object sender, System.Windows.RoutedEventArgs e)
        {
          if (subclasses.isProcessed)
            return;

          Logger.Log(string.Format("subclasses_selected in {0}", GetType().FullName),
              Category.Debug, Priority.None);
          
          ReferenceDataService.GetSubClasses(id, this);
        }

        #region METHOD: Execute() 
        /// <summary>
        /// Executes the specified parameter.
        /// </summary>
        /// <param name="parameter">The parameter.</param>
        public override void Execute(object parameter)
        {
            CompletedEventArgs = (CompletedEventArgs)parameter;
            Logger.Log(string.Format("Execute for type {0} in {1}",
                CompletedEventArgs.CompletedType,
                GetType().FullName), Category.Debug, Priority.None);

            if (CompletedEventArgs.CheckForType(CompletedEventType.GetClass))
            {
              QMXF qmxf = (QMXF)CompletedEventArgs.Data;
              ClassDefinition classDefinition = qmxf.classDefinitions.FirstOrDefault();

              ProcessClassDefinition(classDefinition);

              //GvJ this is breaking the load of the qmxf of the selected item
              //if (this.IsSelectionActive)
              //{
                UpdateModel(qmxf);
              //}

              FillClassDetailView();              
            }
            else if (CompletedEventArgs.CheckForType(CompletedEventType.GetSubClasses))
            {
              List<Entity> entities = (List<Entity>)CompletedEventArgs.Data;

              foreach (Entity entity in entities)
                subclasses.Items.Add(AddTreeItem(entity.label, entity));

              subclasses.itemTextBlock.Text = "Sub Classes (" + entities.Count + ")";
              subclasses.IsExpanded = false;
              subclasses.isProcessed = true;

            }
            else if (CompletedEventArgs.CheckForType(CompletedEventType.GetClassTemplates))
            {
              List<Entity> entities = (List<Entity>)CompletedEventArgs.Data;

              foreach (Entity entity in entities)
                templates.Items.Add(AddTreeItem(entity.label, entity));

              templates.itemTextBlock.Text = "Templates (" + entities.Count + ")";
              templates.IsExpanded = false;
              templates.isProcessed = true;
            }
            else if (CompletedEventArgs.CheckForType(CompletedEventType.GetClassLabel))
            {
              ShowAndSaveLabel(CompletedEventArgs.Data);
            }
        } 
        #endregion

        /// <summary>
        /// Handles the selected event of the templates control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="System.Windows.RoutedEventArgs"/> instance containing the event data.</param>
        public void templates_selected(object sender, System.Windows.RoutedEventArgs e)
        {
          if (templates.isProcessed)
            return;

          Logger.Log(string.Format("templates_selected in {0}", GetType().FullName),
                  Category.Debug, Priority.None);  
          
          ReferenceDataService.GetClassTemplates(id, this);   
        }

        public void ProcessClassDefinition(ClassDefinition classDefinition)
        {
  
          //Image image = null;
          ClassDefinition = classDefinition;
          Tag = classDefinition;

          classifications = Container.Resolve<CustomTreeItem>();

          classifications.SetImageSource("folder.png");
          classifications.SetTooltipText("Classification Collection...");
          classifications.itemTextBlock.Text = "Classifications";
         // classifications.Header = "Classifications";
          classifications.Selected += classifications_selected;
          this.Items.Add(classifications);
          superclasses = Container.Resolve<CustomTreeItem>();

          superclasses.SetImageSource("folder.png");
          superclasses.SetTooltipText("Super Class Collection...");
          superclasses.SetTextBlockText("Super Classes");

         // superclasses.Header = "Super Classes";
          superclasses.Selected += superclasses_selected;
          this.Items.Add(superclasses);

          subclasses = Container.Resolve<CustomTreeItem>();
          subclasses.SetTooltipText("Sub Class Collection...");
          subclasses.SetImageSource("folder.png");
          subclasses.SetTextBlockText("Sub Classes");
         
          //subclasses.Header = "Sub Classes";
          subclasses.Selected += subclasses_selected;
          this.Items.Add(subclasses);

          templates = Container.Resolve<CustomTreeItem>();
          templates.SetTooltipText("Template Collection...");
          templates.SetImageSource("folder.png");
          templates.SetTextBlockText("Templates");

         // templates.Header = "Templates";
          templates.Selected += templates_selected;
          this.Items.Add(templates);

          isProcessed = true;
        }
    }
}
